//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System.Collections;
using CommunityServer.Components;

namespace CommunityServer.Discussions.Components {
	// *********************************************************************
    //  ForumGroups
    //
    /// <summary>
    /// This class contains methods for working with the Forum Groups.
    /// </summary>
    /// 
    // ********************************************************************/ 
    public class ForumGroups {


        public static bool IsPublic(int groupid)
        {
            ArrayList list = Forums.GetForumsByForumGroupID(groupid,true,true,false,true);
            return Sections.FilterByAccessControl(list,Permission.View | Permission.Read, Users.GetAnonymousUser(true)).Count > 0;
        }

		public static void Update(Group g)
		{
			Groups.UpdateGroup(g);
			CSCache.Remove(CacheKey(CSContext.Current));
		}

        // *********************************************************************
        //  GetForumGroupByForumID
        //
        /// <summary>
        /// Returns the forum group for a given forum id.
        /// </summary>
        /// <param name="forumID">Forum id used to lookup forum</param>
        /// 
        // ********************************************************************/ 
        public static Group GetForumGroupByForumID (int forumID) {
            return GetForumGroupByForumID (forumID, true, false);
        }

        public static Group GetForumGroupByForumID (int forumID, bool cacheable) {
            return GetForumGroupByForumID (forumID, cacheable, false);
        }

        public static Group GetForumGroupByForumID (int forumID, bool cacheable, bool ignorePermissions) {
            int forumGroupID;
        	Hashtable forumGroups;
            Forum forum;

            // Get the related forum
            //
            forum = Forums.GetForum(forumID);

            // Get the forum groups hashtable
            //
            forumGroups = GetForumGroupsTable(cacheable, ignorePermissions, false, false, CSContext.Current.User);

            // Get the forum group id
            //
            forumGroupID = forum.GroupID;

            // Return the forum group
            //
            if (forumGroups[forumGroupID] == null)
                throw new CSException(CSExceptionType.GroupNotFound, forumGroupID.ToString());

            return (Group) forumGroups[forumGroupID];
        }


        // *********************************************************************
        //  GetForumGroup
        //
        /// <summary>
        /// Returns the forum group for a given forum group id.
        /// </summary>
        /// <param name="forumGroupID">Forum group id to return a forum group for.</param>
        /// <returns>The total number of forums.</returns>
        /// 
        // ********************************************************************/ 
        public static Group GetForumGroup (int forumGroupID) {
            return GetForumGroup(forumGroupID, true, false);
        }

        public static Group GetForumGroup (int forumGroupID, bool cacheable) {
            return GetForumGroup(forumGroupID, cacheable, false);
        }

        public static Group GetForumGroup (int forumGroupID, bool cacheable, bool ignorePermissions) {
            CSContext csContext = CSContext.Current;

            return GetForumGroup (forumGroupID, cacheable, ignorePermissions, csContext.User.UserID);

        }

        public static Group GetForumGroup (int forumGroupID, bool cacheable, bool ignorePermissions, int userID) {

            // Get the forum groups hashtable
            //
           Hashtable forumGroups = GetForumGroupsTable(cacheable, ignorePermissions, false, false, CSContext.Current.User);

            // Return the forum group
            //
            if (forumGroups[forumGroupID] == null)
                throw new CSException(CSExceptionType.GroupNotFound, forumGroupID.ToString());

            return (Group) forumGroups[forumGroupID];

        }



        // *********************************************************************
        //  GetAllForumGroups
        //
        /// <summary>
        /// Returns a list of all forum groups
        /// </summary>
        /// <param name="displayForumGroupsNotApproved">If true returns all forum groups</param>
        /// <param name="allowFromCache">Whether or not the request can be satisfied from the Cache</param>
        /// 
        // ********************************************************************/ 
        public static ArrayList GetForumGroups (bool cacheable) {

            return GetForumGroups(cacheable, false);
        }

        public static ArrayList GetForumGroups (bool cacheable, bool ignorePermissions) {

            return GetForumGroups(cacheable, ignorePermissions, CSContext.Current.User);
        }

		public static ArrayList GetForumGroups (bool cacheable, bool ignorePermissions, User user)
		{
			return GetForumGroups(cacheable, ignorePermissions,false, false, user);
		}

		public static ArrayList GetForumGroups (bool cacheable, bool ignorePermissions, bool flush)
		{
			return GetForumGroups(cacheable, ignorePermissions,flush, false, CSContext.Current.User);
		}

		public static ArrayList GetForumGroups (bool cacheable, bool ignorePermissions, bool flush, bool requireModeration) {
			return GetForumGroups(cacheable, ignorePermissions,flush, requireModeration, CSContext.Current.User);
		}

        public static ArrayList GetForumGroups (bool cacheable, bool ignorePermissions, bool flush, bool requireModeration, User user) {
            ArrayList forumGroups = new ArrayList();
            Hashtable forumGroupsTable;

            // Get the ForumGroups as a hashtable
            //
            forumGroupsTable = GetForumGroupsTable(cacheable, ignorePermissions, flush, requireModeration, user);

            // Hide forum groups based on the user's cookie
            //
            
            //forumGroupsTable = Groups.HideGroups(forumGroupsTable);

            // Convert the hashtable to an arraylist
            //
            foreach(Group fg in forumGroupsTable.Values)
                forumGroups.Add( fg );

            // Sort the forum groups
            //
            forumGroups.Sort();

            return forumGroups;
        }

		public static ArrayList GetFilteredForumGroups()
		{
				User user = CSContext.Current.User;
				Hashtable forumGroupsTable = GetForumGroupsTable(true, false, false, false, user);
				forumGroupsTable = Groups.HideUsersGroups(forumGroupsTable,user);
				ArrayList al = new  ArrayList(forumGroupsTable.Values);
			al.Sort();
			return al;

		}

		private static string CacheKey(CSContext context)
		{
			return string.Format("AllForumGroups-{0}",context.SiteSettings.SettingsID );
		}

        private static Hashtable GetForumGroupsTable(bool cacheable, bool ignorePermissions, bool flush, bool requireModeration, User user) {
			//string cacheKey = string.Format("AllForumGroups-{0}-Cacheable:{1}-IgnorePermissions:{2}",CSContext.Current.SiteSettings.SettingsID,cacheable,ignorePermissions);
			 
			CSContext csContext = CSContext.Current;
			string cacheKey = CacheKey(csContext);
            Hashtable unfilteredForumGroups;
            Hashtable forumGroups;

			if(flush)
			{
				CSCache.Remove(cacheKey);
                csContext.Items[cacheKey] = null;
			}

            unfilteredForumGroups = csContext.Items[cacheKey] as Hashtable;

            if(unfilteredForumGroups != null)
                return unfilteredForumGroups;

            // Get the raw forum groups
            //
            unfilteredForumGroups = CSCache.Get(cacheKey) as Hashtable;
            if ( unfilteredForumGroups == null ) {
                unfilteredForumGroups = CommonDataProvider.Instance().GetGroups(ApplicationType.Forum, requireModeration);

                if (cacheable)
                    CSCache.Insert(cacheKey,unfilteredForumGroups,10 * CSCache.MinuteFactor);

            } 

            forumGroups = new Hashtable();

            foreach (Group f in unfilteredForumGroups.Values) 
            {
				if (requireModeration)
				{
					if (CommunityServer.Discussions.Controls.Moderate.GetForumsByForumGroupID(f.GroupID).Count > 0)
						forumGroups.Add(f.GroupID, f.Clone());
				}
				else if(ignorePermissions || !cacheable)
					forumGroups.Add(f.GroupID,f.Clone());
				else if (Forums.GetForumsByForumGroupID(f.GroupID, cacheable, ignorePermissions).Count > 0)
					forumGroups.Add(f.GroupID, f.Clone());

            }

            csContext.Items[cacheKey] = forumGroups;

            return forumGroups;

       }

        
        // *********************************************************************
        //  DeleteForumGroup
        //
        /// <summary>
        /// Deletes a forum group.
        /// </summary>
        /// <param name="forumGroupID">ID of forum group to delete.</param>
        // ********************************************************************/ 
        public static void DeleteForumGroup (int forumGroupID)
		{
            Group f = ForumGroups.GetForumGroup(forumGroupID, false);
            Groups.DeleteGroup(f);
        }


		/// <summary>
		/// Returns true if the Group has Sections
		/// </summary>
		public static bool HasChildSections(int groupID)
		{
			return CommunityServer.Discussions.Components.Forums.GetForumsByForumGroupID(groupID,false,true,true,false).Count > 0;
		}


    }
}
